package org.mirrentools.remoteattendance.admin.common;

import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.HttpResponse;
import org.mirrentools.remoteattendance.admin.MainApplication;

import java.util.Objects;

public class Requests {
  /**
   * 主机地址
   */
  public final static String HOST = MainApplication.OPTIONS.host();
  /**
   * 参数名称uid
   */
  public final static String NAME_UID = "uid";
  /**
   * 参数名称uid
   */
  public final static String NAME_FINAL_UID = "finalUid";
  /**
   * 参数名称token
   */
  public final static String NAME_TOKEN = "token";

  /**
   * 检查用户的id或token是否正确
   */
  public final static String PATH_CHECK_TOKEN = HOST + "/api/users/checkToken";
  /**
   * 管理员获取用户的列表
   */
  public final static String PATH_ADMIN_FIND_USERS = HOST + "/admin/api/find/users";
  /**
   * 获取用户月份考勤统计
   */
  public final static String PATH_FIND_MONTH_RECORD = HOST + "/api/record/findMonths";
  /**
   * 获取每小时考勤记录
   */
  public final static String PATH_FIND_DAYS_RECORD = HOST + "/api/record/findDays";
  /**
   * 行事历分类
   */
  public final static String PATH_FIND_CALENDAR_GROUP = HOST + "/api/record/findCalendarGroup";
  /**
   * 行事历与用户的考勤状态
   */
  public final static String PATH_FIND_CALENDAR = HOST + "/api/record/findCalendar";


  /**
   * 接口请求
   *
   * @param url 请求的URL
   */
  public static Future<JsonObject> get(String url) {
    Promise<JsonObject> promise = Promise.promise();
    get(url, promise);
    return promise.future();
  }

  /**
   * 接口请求
   *
   * @param url     请求的URL
   * @param handler 操作结果
   */
  public static void get(String url, Handler<AsyncResult<JsonObject>> handler) {
    try {
      request(MainApplication.WEB_CLIENT.getAbs(url), handler);
    } catch (Throwable e) {
      handler.handle(Future.failedFuture(e));
    }
  }


  /**
   * 接口请求
   *
   * @param url   请求的URL
   * @param query 请求的url参数
   */
  public static Future<JsonObject> get(String url, MultiMap query) {
    Promise<JsonObject> promise = Promise.promise();
    get(url, query, promise);
    return promise.future();
  }

  /**
   * 接口请求
   *
   * @param url     请求的URL
   * @param query   请求的url参数
   * @param handler 操作结果
   */
  public static void get(String url, MultiMap query, Handler<AsyncResult<JsonObject>> handler) {
    try {
      HttpRequest<Buffer> abs = MainApplication.WEB_CLIENT.getAbs(url);
      abs.queryParams().addAll(query);
      request(abs, handler);
    } catch (Throwable e) {
      handler.handle(Future.failedFuture(e));
    }
  }

  /**
   * 接口请求
   *
   * @param url  请求的URL
   * @param body 请求表单参数
   */
  public static Future<JsonObject> post(String url, MultiMap body) {
    Promise<JsonObject> promise = Promise.promise();
    post(url, body, promise);
    return promise.future();
  }

  /**
   * 接口请求
   *
   * @param url     请求的URL
   * @param body    请求表单参数
   * @param handler 操作结果
   */
  public static void post(String url, MultiMap body, Handler<AsyncResult<JsonObject>> handler) {
    try {
      HttpRequest<Buffer> abs = MainApplication.WEB_CLIENT.postAbs(url);
      request(abs, body, null, handler);
    } catch (Throwable e) {
      handler.handle(Future.failedFuture(e));
    }
  }

  /**
   * 接口请求
   *
   * @param url  请求的URL
   * @param body 请求表单参数
   */
  public static Future<JsonObject> uploadFile(String url, Buffer body) {
    Promise<JsonObject> promise = Promise.promise();
    uploadFile(url, body, promise);
    return promise.future();
  }

  /**
   * 接口请求
   *
   * @param url     请求的URL
   * @param body    请求的数据
   * @param handler 操作结果
   */
  public static void uploadFile(String url, Buffer body, Handler<AsyncResult<JsonObject>> handler) {
    try {
      HttpRequest<Buffer> abs = MainApplication.WEB_CLIENT.postAbs(url);
      request(abs, null, body, handler);
    } catch (Throwable e) {
      handler.handle(Future.failedFuture(e));
    }
  }


  /**
   * 接口请求
   *
   * @param request 请求的基本信息
   */
  public static Future<JsonObject> request(HttpRequest<Buffer> request) {
    Promise<JsonObject> promise = Promise.promise();
    request(request, promise);
    return promise.future();
  }

  /**
   * 接口请求
   *
   * @param request 请求的基本信息
   * @param handler 操作结果
   */
  public static void request(HttpRequest<Buffer> request, Handler<AsyncResult<JsonObject>> handler) {
    request(request, null, null, handler);
  }

  /**
   * 接口请求
   *
   * @param request  请求的基本信息,如果query中没有uid或token则会添加系统默认的uid与token
   * @param multiMap body的请求信息
   * @param buffer   body的请求信息,如果它不为空则multiMap无效
   * @param handler  操作结果
   */
  public static void request(HttpRequest<Buffer> request, MultiMap multiMap, Buffer buffer, Handler<AsyncResult<JsonObject>> handler) {
    try {
      request.addQueryParam(NAME_UID, MainApplication.OPTIONS.uid());
      request.addQueryParam(NAME_TOKEN, MainApplication.OPTIONS.token());
      Future<HttpResponse<Buffer>> future;
      if (buffer != null) {
        future = request.sendBuffer(buffer);
      } else if (multiMap == null) {
        future = request.send();
      } else {
        future = request.sendForm(multiMap);
      }
      future.onSuccess(resp -> {
        if (resp.statusCode() == 200) {
          try {
            JsonObject body = resp.bodyAsJsonObject();
            if (body == null || body.isEmpty()) {
              handler.handle(Future.failedFuture("Response is empty"));
              return;
            }
            if (Objects.equals(200, body.getInteger("code"))) {
              handler.handle(Future.succeededFuture(body));
            } else {
              handler.handle(Future.failedFuture(body.encode()));
            }
          } catch (Exception e) {
            handler.handle(Future.failedFuture(e));
          }
        } else {
          handler.handle(Future.failedFuture("status:" + resp.statusCode() + ",msg:" + resp.statusMessage()));
        }
      });
      future.onFailure(err -> handler.handle(Future.failedFuture(err)));
    } catch (Throwable e) {
      handler.handle(Future.failedFuture(e));
    }
  }


}
